package com.smart.manager.finance.repository;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.RandomUtil;
import com.smart.common.entities.core.Page;
import com.smart.manager.finance.entities.bodys.RPopApply;
import com.smart.manager.finance.entities.enums.ApplyState;
import com.smart.manager.finance.entities.enums.ApplyType;
import com.smart.manager.finance.entities.models.FinancePopApply;
import com.smart.manager.finance.entities.models.query.QFinancePopApply;
import com.smart.manager.pop.entities.enums.BillKind;
import com.smart.manager.pop.entities.enums.BillState;
import com.smart.manager.pop.entities.models.PopDisInviter;
import com.smart.manager.pop.entities.views.InviterView;
import com.smart.manager.pop.repository.DisBillRepository;
import com.smart.manager.pop.repository.DisInviterRepository;
import io.ebean.annotation.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Optional;


/**
 * 流水库
 *
 * @author leo
 * @date 2023/07/26
 */
@Service
@Log4j2
@RequiredArgsConstructor
public class ApplyRepository {

    private final DisInviterRepository inviterRepository;
    private final DisBillRepository disBillRepository;

    /**
     * 查询搜索
     *
     * @param search 搜索
     * @return {@link Page}<{@link FinancePopApply}>
     */
    public Page<FinancePopApply> pageList(RPopApply.SearchBody search) {
        QFinancePopApply query = new QFinancePopApply();
        Opt.ofBlankAble(search.getCode()).ifPresent(x -> query.code.eq(x));
        Opt.ofBlankAble(search.getPhone()).ifPresent(x -> query.agent.phone.contains(x));
        query.order().id.desc();
        query.setFirstRow(search.firstRow()).setMaxRows(search.maxRows());
        return new Page<FinancePopApply>().load(query.findPagedList());
    }

    /**
     * 申请提现
     *
     * @param amount 量
     */
    @Transactional
    public void add(Long id, BigDecimal amount) {
        PopDisInviter inviter = inviterRepository.getOneById(id);
        Assert.notNull(inviter.getQrPay(), "请先上传收款二维码在来提现");
        InviterView inviterView = BeanUtil.copyProperties(inviter, InviterView.class);
        //1.扣除提现金额  建立流水/台账
        inviterRepository.addBill(inviterView, BillKind.WITHDRAW, amount, "佣金提现申请成功,等待审核",false);
        //2.建立提现申请
        new FinancePopApply()
                .setCode(generateTradeNo())
                .setAgent(inviterView)
                .setAmount(amount)
                .setStatus(ApplyState.UNDERREVIEW)
                .setType(ApplyType.WITHDRAWALS).insert();
    }

    /**
     * 审核提现
     *
     * @param id   id
     * @param body 身体
     */
    @Transactional
    public void process(Long id,RPopApply.EditBody body) {
        FinancePopApply apply = getOne(id);
        Assert.equals(apply.getStatus(), ApplyState.UNDERREVIEW, "当前提现申请已经处理!");
        PopDisInviter inviter = inviterRepository.getOneById(apply.getAgent().getId());
        //插入流水信息
        if (body.getStatus()) {
            disBillRepository.puxData(BeanUtil.copyProperties(inviter,InviterView.class),BillState.REVENUE,BillKind.RECEIPT,apply.getAmount(),"成功提现到零钱");
            apply.setStatus(ApplyState.SUCCESS).setDescription("成功提现到零钱").update();
        } else {
            disBillRepository.puxData(BeanUtil.copyProperties(inviter,InviterView.class),BillState.REVENUE,BillKind.RECEIPT,apply.getAmount(),"扣除佣金已退还 原因:"+body.getDescription());
            apply.setStatus(ApplyState.FAIL).setDescription("扣除佣金已退还").update();
        }
    }

    private FinancePopApply getOne(Long id) {
        Optional<FinancePopApply> apply = new QFinancePopApply().id.eq(id).findOneOrEmpty();
        Assert.isFalse(apply.isEmpty(), "未找到提现申请!");
        return apply.get();
    }

    /**
     * 生成订单id 长度为25个随机字符串
     *
     * @return {@code String}
     */
    private String generateTradeNo() {
        String x = DateUtil.format(new Date(), "yyyyMMddHHmmss").concat(RandomUtil.randomNumbers(5));
        return "TX".concat(x);
    }
}
